\documentclass[11pt]{report}

\usepackage{listings}
\usepackage{courier}

\title{SaneSockets v0.2}
\author{Samuel C. Payson}
\date{{\small Last Updated \today}}

\begin{document}
\maketitle
\tableofcontents

\chapter*{License}

Copyright 2010 Samuel C. Payson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

\begin{enumerate}
\item Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 
\item Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.  
\end{enumerate}

THIS SOFTWARE IS PROVIDED BY SAMUEL C. PAYSON ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SAMUEL C. PAYSON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  

The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Samuel C. Payson.


\chapter{About SaneSockets}

SaneSockets is a C-Language wrapper for the Berkeley Sockets Library. It is designed to make networked applications easier to understand and implement for C and C++ programmers. The Berkeley Sockets Library itself offers more control, and is probably a more suitable alternative for applications which require this degree of control.

SaneSockets abstracts away many of the more complicated aspects of sockets programming with minimal cost to performance.

The following document summarizes SaneSockets' approach to TCP and UDP sockets and provides the reader with example code and function descriptions. Also provided are example client-server implementations for both socket types.

\subsubsection{Problems With This Document}
Right now this document is somewhat poorly constructed and the example-programs are imperfect. Please understand that this document is as new as the library itself and likewise will improve with time. Any suggestions, bugs, or comments can be sent to {\footnotesize \verb scpayson@gmail.com } in a message with `sanesockets' somewhere in the subject.

\subsubsection{Additional Resources}

Anyone interested learning more extensively about network programming should check out \emph{Beej's Guide to Network Programming} at \linebreak {\footnotesize{\verb http://beej.us/guide/bgnet/ }}. It is an excellent source for information about Sockets programming.

\chapter{Installing SaneSockets}

Currently SaneSockets only supports Linux operating systems, and even then is not garunteed to work with your particular distribution (eventual support for all of the most common operating systems is intended). In order to install the library, {\footnotesize{\verb cd }} to the directory of your {\footnotesize \verb libssock-0.1 } folder, and run `{\footnotesize{\verb sudo  \verb make  \verb install }}'. This will compile the library and move files to the correct directories. The library requires {\footnotesize{\verb gcc }} and {\footnotesize{\verb ar }} to compile.

In the event that this script fails, try `{\footnotesize \verb sh  \verb install.sh }'. If that fails take a look at the commands inside, you should end up with the following folders in the named directories.

\begin{enumerate}
\item {\footnotesize{\verb /usr/include/ssock/ssock.h }}
\item {\footnotesize{\verb /usr/include/ssock/ssock_tcpsock.h }}
\item {\footnotesize{\verb /usr/include/ssock/ssock_udpsock.h }}
\item {\footnotesize{\verb /usr/include/ssock/ssock_system.h }}
\item {\footnotesize{\verb /usr/lib/libssock.a }}
\end{enumerate}

As listed in {\footnotesize \verb install.sh }, the commands to generate {\footnotesize \verb libssock.a } are as follows, and should be run in your {\footnotesize{\verb libssock-0.1 }} folder. If these commands fail, you should make sure you have the correct programs installed and that at least the final command ({\footnotesize \verb ar }) is run as root.

\footnotesize
\begin{verbatim}
gcc -c -Wall src/ssock_tcpsock.c -o o/ssock_tcpsock.o
gcc -c -Wall src/ssock_udpsock.c -o o/ssock_udpsock.o
ar rvs /usr/lib/libssock.a o/ssock_tcpsock.o o/ssock_udpsock.o
\end{verbatim}
\normalsize

\chapter{TCP Sockets}

\section{Data Types}

\subsection{General Data Types}

SaneSockets defines two data types which are used throughout the library, they are just renamed versions of existing types designed to make the code easier to understand. They are as follows


\lstset{language=C, basicstyle=\footnotesize \ttfamily, showstringspaces=false, frame=single} 

{\small \begin{lstlisting}
typedef int SOCKET;

typedef unsigned char byte;
\end{lstlisting} }

\subsection{TCP Socket Type}

The data-structure used by SaneSockets to represent a TCP Socket is \linebreak {\footnotesize{\verb ssock_tcpsocket }}, shown below in its entirety.

{\small \begin{lstlisting}
typedef struct
{
      struct addrinfo tcp_ai;
      SOCKET tcp_fd; //file descriptor
      unsigned short tcp_port;
}ssock_tcpsocket;
\end{lstlisting} }

This struct should never be accessed directly unless you are comfortable with the Berkeley Sockets Library and intend to manipulate the file descriptor directly.

In general, the TCP functions take a pointer to {\footnotesize{\verb ssock_tcpsocket }} as their first argument.

\section{Methods}

The SaneSockets library has seven methods for use specifically with TCP Sockets, all are declared in {\footnotesize{\verb ssock_tcpsock.h }} which is included by {\footnotesize{\verb ssock.h }}. For all applicable functions, if an error occurs {\footnotesize{\verb errno }} will be set to the proper socket error.

\bigskip

{\small \begin{lstlisting}
ssock_tcpsocket *ssock_newtcp(const char *node, const char *port)
\end{lstlisting} }
{\footnotesize{\verb ssock_newtcp }} first resolves {\footnotesize{\verb node }} which is either a domain name \linebreak (i.e. {\footnotesize{\verb www.google.com }}), an IPv4 address (i.e. {\footnotesize{\verb 127.0.0.1 }}), or an IPv6 address (i.e. {\footnotesize{\verb fe80::221:6aff:fe91 }}), and then creates a new TCP Socket for connecting to {\footnotesize{\verb node }} on {\footnotesize{\verb port }}. To create a listening socket, pass {\footnotesize \verb NULL } as {\footnotesize \verb node }. Returns {\footnotesize{\verb NULL }} in the event of error.

\bigskip

{\small \begin{lstlisting}
int ssock_tcpconnect(ssock_tcpsocket *sock)
\end{lstlisting} }
{\footnotesize{\verb ssock_tcpconnect }} opens an actual TCP connection. Returns {\footnotesize{\verb -1 }} in the event of error.

\bigskip

{\small \begin{lstlisting}
void ssock_tcpclose(ssock_tcpsocket *sock)
\end{lstlisting} }
{\footnotesize{\verb ssock_tcpclose }} terminates a TCP stream.


\bigskip

{\small \begin{lstlisting}
int ssock_tcpsend(ssock_tcpsocket *sock, void *data, size_t sz)
\end{lstlisting} }
{\footnotesize{\verb ssock_tcpsend }} will read {\footnotesize{\verb sz }} bytes from the buffer pointed to by {\footnotesize{\verb data }} and send them to {\footnotesize{\verb sock }}. Returns {\footnotesize{\verb -1 }} in the event of an error, otherwise returns the number of bytes sent.

\bigskip

{\small \begin{lstlisting}
int ssock_tcprecv(ssock_tcpsocket *sock, void *buff, size_t sz)
\end{lstlisting} }
{\footnotesize{\verb ssock_tcprecv }} will place the next {\footnotesize{\verb sz }} bytes recieved from {\footnotesize{\verb sock }} and place them, in order, into the memory pointed to by {\footnotesize{\verb buff }}. Returns {\footnotesize{\verb -1 }} in the event of an error, otherwise returns the number of bytes received.

\bigskip

{\small \begin{lstlisting}
int ssock_tcprecv_next(ssock_tcpsocket *sock, void *buff, size_t sz)
\end{lstlisting} }
{\footnotesize{\verb ssock_tcprecv_next }} will copy any data waiting on {\footnotesize \verb sock } into the memory pointed to by {\footnotesize{\verb buff }}, up to {\footnotesize \verb sz } bytes. If there are less than {\footnotesize \verb sz } bytes waiting, {\footnotesize{\verb ssock_tcprecv_next }} will not wait for more (unlike {\footnotesize{\verb ssock_tcprecv }}). Returns {\footnotesize{\verb -1 }} in the event of an error, otherwise returns the number of bytes received.

\bigskip

{\small \begin{lstlisting}
ssock_tcpsocket *ssock_tcpaccept(ssock_tcpsocket *listener)
\end{lstlisting} }
{\footnotesize{\verb ssock_tcpaccept }} opens a TCP connection with a socket which is attempting to connect to {\footnotesize{\verb listener }}. Returns a connected socket, or in the case of error, {\footnotesize{\verb NULL }}.

\pagebreak

\section{Example Client}

\lstset{frame=none}

{\small \begin{lstlisting}
//TCPClient.c
#include <stdio.h>
#include <stdint.h>
#include <ssock/ssock.h>

int main()
{
	ssock_tcpsocket * connector;
	char msg[128];
	int sent;
	uint32_t msgLength;
	
	//Create a new socket for connecting to localhost
	//on port 12345
	connector = ssock_newtcp("127.0.0.1", "12345");
	
	//Initiate the connection on socket 'connector'
	ssock_tcpconnect(connector);
	fgets(msg, 128, stdin);
	msgLength = strlen(msg) + 1;

	//Send a packet containing the size of the message
	sent = sock_tcpsend(connector, &msgLength, sizeof(uint32_t));

	//Send the message itself
	sent += ssock_tcpsend(connector, msg, msgLength);
	printf("%d bytes sent.\n", sent);

	//Close the socket when we're done with it
	ssock_tcpclose(connector);
	
	//Free the memory we used
	ssock_freetcp(connector);
	return 0;
}
\end{lstlisting} }

\pagebreak

\section{Example Server}

{\small \begin{lstlisting}
//TCPServer.c
#include <stdio.h>
#include <stdint.h>
#include <ssock/ssock.h>

int main()
{
	ssock_tcpsocket *listener, *client;
	char msg[128];
	int recvd;
	uint32_t msgLength;
	
	//Create a Socket for listening on port 12345
	listener = ssock_newtcp(NULL, "12345");
	
	//Accept the first requested connection
	client = ssock_tcpaccept(listener);
	
	//Close the Listener
	ssock_tcpclose(listener);
	
	//Recieve the size of the incoming message
	recvd = ssock_tcprecv(client, &msgLength, sizeof(uint32_t))
	
	//Receive the message itself
	recvd += ssock_tcprecv(client, msg, msgLength);
	printf("%d bytes received:\n%s\n", recvd, msg);
	
	//Close the client connection with the client
	ssock_tcpclose(client);
	
	//Free the memory we used
	ssock_freetcp(listener);
	ssock_freetcp(client);
	return 0;
}
\end{lstlisting} }

\chapter{UDP Sockets}

\section{UDP Socket Type}

The data-structure used by SaneSockets to represent a UDP Socket is {\footnotesize \verb ssock_udpsocket }, shown below in its entirety.

\lstset{frame=single}
{\small \begin{lstlisting}
typedef struct
{
	SOCKET udp_fd;
	struct addrinfo udp_ai;
	struct sockaddr * udp_addr;
	unsigned short udp_port;
	struct sockaddr_storage udp_last; //Last recieved from
	size_t udp_llen; //Size in bytes of udp_last
}ssock_udpsocket;
\end{lstlisting} }

Like with {\footnotesize \verb ssock_tcpsocket }, this struct should never be accessed directly unless you really know what you're doing. However, there is no built-in use for {\footnotesize \verb udp_last } and {\footnotesize \verb udp_llen }. They are set every time a packet is recieved, but if you wish to extract information from them you will have to make use of the Berkeley Sockets Library.

As with the TCP Sockets, most UDP functions take a pointer to \linebreak {\footnotesize \verb ssock_udpsocket } as their first argument.

\pagebreak

\section{Methods}

Because UDP Sockets are connectionless, the functions required to interact with them are considerably fewer. The following four functions represent SaneSockets' UDP interface.
\bigskip
{\small \begin{lstlisting}
ssock_udpsocket *ssock_newudp(const char *host, const char *port)
\end{lstlisting} }
{\footnotesize \verb ssock_newudp } creates a new socket for sending data to {\footnotesize \verb host } on {\footnotesize \verb port }. To create a listening socket, one designed for recieving data on a certain port, pass {\footnotesize \verb NULL } as the first argument.

\bigskip

{\small \begin{lstlisting}
int ssock_udpsend(ssock_udpsocket *sock, void *data, size_t sz)
\end{lstlisting} }
{\footnotesize \verb ssock_udpsend } will send {\footnotesize \verb sz } bytes of data from the memory pointed to by {\footnotesize \verb data } and send them to {\footnotesize \verb sock } in UDP Packets. This data may or may not arrive, and if it does may be in any order. 

\bigskip

{\small \begin{lstlisting}
int ssock_udprecv(ssock_udpsocket *sock, void *buff, size_t sz)
\end{lstlisting} }
{\footnotesize \verb ssock_udprecv } is the inverse of {\footnotesize \verb ssock_udpsend }. It will take the last up-to {\footnotesize \verb sz } bytes of data recieved and place them into the buffer pointed to by {\footnotesize \verb buff }.

\bigskip

{\small \begin{lstlisting}
void ssock_freeudp(ssock_udpsocket *sock)
\end{lstlisting} }
{\footnotesize \verb ssock_freeudp } frees the memory used by {\footnotesize \verb sock }.

\pagebreak

\section{Example Client}

\lstset{frame=none}
{\small \begin{lstlisting}
//UDPClient.c
#include <stdio.h>
#include <ssock/ssock.h>

int main()
{
	int i, nbrBytes;
	char buff[128];
	
	//Create a Listening UDP Socket on port 12345
	ssock_udpsocket * listen = ssock_newudp(NULL, "12345");
	
	//Print the first 50 packets sent to us
	for (i = 0; i < 50; ++i)
	{
		nbrBytes = ssock_udprecv(listen, buff, 128);
		printf("%d bytes received: %s", nbrBytes, buff);
	}
      
	//Free the memory we used
	ssock_freeudp(listen);
	return 0;
}
\end{lstlisting} }

\pagebreak

\section{Example Server}

{\small \begin{lstlisting}
//UDPServer.c
#include <stdio.h>
#include <ssock/ssock.h>

int main()
{
	int i;
	const char * msg = "DATAGRAM!!!";
	
	//Create a new Socket for sending data to localhost
	//on port 12345
	ssock_udpsocket * talker = ssock_newudp("127.0.0.1", "12345");
	
	//Send msg to localhost 50 times
	for (i = 0; i < 50; ++i)
	{
		ssock_udpsend(talker, msg, 12);
	}
	
	//Free the memory we used
	ssock_freeudp(talker);
	return 0;
}
\end{lstlisting} }

\end{document}
